package utils

import (
	"fmt"
	"reflect"
	"strings"
)

// ReflectHandleStuct  通过反射处理 sql条件 必须传递指针类型
func ReflectHandleStuct(value interface{}) string {
	sql := ""
	val := reflect.ValueOf(value).Elem() //获取字段值
	typ := reflect.TypeOf(value).Elem()  //获取字段类型
	//循环遍历struct 中的字段
	for i := 0; i < typ.NumField(); i++ {
		fiedName := typ.Field(i).Name
		fiedType := typ.Field(i).Type
		b := val.Field(i).IsZero() //是否为空，或默认值
		v := val.FieldByName(fiedName).Interface()
		//获取字段的值
		if v != "" && !b {
			//时间类型的参数需要在业务中单独处理
			if fiedType.String() == "time.Time" || fiedType.String() == "spec.LocalTime" {
				continue
			}
			dbFieldStr := ""
			//获取数据库字段名
			dbField := typ.Field(i).Tag.Get("gorm")
			//处理数据库字段
			split := strings.Split(dbField, ";")
			for _, s := range split {
				if strings.Contains(s, "column") {
					//分割获取数据库字段值
					dbFieldStr = strings.Split(s, ":")[1]
				}
			}
			if dbFieldStr == "" || dbFieldStr == "-" {
				//非数据库字段
				continue
			}
			//字段非空 拼接sql
			if sql == "" {
				sql = dbFieldStr + " = '" + fmt.Sprint(v) + "'"
			} else {
				sql += " AND "
				sql += dbFieldStr + " = '" + fmt.Sprint(v) + "'"
			}
		}
	}
	if sql == "" {
		return ""
	}
	return sql
}

// ReflectHandleStuctMap  通过反射处理 k/v  k为数据库字段
func ReflectHandleStuctMap(value interface{}) map[string]interface{} {
	result := make(map[string]interface{}, 0)
	val := reflect.ValueOf(value).Elem() //获取字段值
	typ := reflect.TypeOf(value).Elem()  //获取字段类型
	//循环遍历struct 中的字段
	for i := 0; i < typ.NumField(); i++ {
		fiedName := typ.Field(i).Name
		b := val.Field(i).IsZero() //是否为空，或默认值
		v := val.FieldByName(fiedName).Interface()
		//获取字段的值
		dbFieldStr := ""
		//获取数据库字段名
		dbField := typ.Field(i).Tag.Get("gorm")
		//处理数据库字段
		split := strings.Split(dbField, ";")
		for _, s := range split {
			if strings.Contains(s, "column") {
				//分割获取数据库字段值
				dbFieldStr = strings.Split(s, ":")[1]
			}
		}
		if dbFieldStr == "" || dbFieldStr == "-" {
			//非数据库字段
			continue
		}
		if b || v == "" {
			result[dbFieldStr] = ""
		} else {
			result[dbFieldStr] = v
		}
	}
	return result
}
